package main

import (
	"fmt"
	"math/rand"
	"strconv"
	"sync"
	"time"
)

//使用goroutine和channel实现一个计算int64随机数各位数和的程序。
//开启一个goroutine循环生成int64类型的随机数，发送到jobChan
//开启24个goroutine从jobChan中取出随机数计算各位数的和，将结果发送到resultChan
//主goroutine从resultChan取出结果并打印到终端输出
//为了保证业务代码的执行性能将之前写的日志库改写为异步记录日志方式。

var wg sync.WaitGroup

func main() {
	start := time.Now()
	jobChan := make(chan int64, 100)
	resultChan := make(chan int64, 100)
	go generateRandomInt64(jobChan)
	wg.Add(1)
	for i := 0; i < 24; i++ {
		go getRandomAndCompute(resultChan, jobChan)
		wg.Add(1)
	}
	wg.Wait()
	close(resultChan)
	for result := range resultChan {
		fmt.Println(result)
	}
	end := time.Now()
	fmt.Println(end.Sub(start))
}

//开启一个goroutine循环生成int64类型的随机数，发送到jobChan
func generateRandomInt64(jobChan chan<- int64) {
	defer wg.Done()
	for i := 0; i < 24; i++ {
		num := rand.Int63()
		fmt.Printf("rand:(%v)\n", num)
		jobChan <- num
	}
	close(jobChan)
}

//开启24个goroutine从jobChan中取出随机数计算各位数的和，将结果发送到resultChan
func getRandomAndCompute(resultChan chan<- int64, jobChan <-chan int64) {
	defer wg.Done()
	for num := range jobChan {
		lenNum := len(strconv.FormatInt(num, 10))
		int64num := num
		var sum int64 = 0
		for i := 1; i < lenNum; i++ {
			last := int64num % 10
			sum = sum + last
			int64num = int64num / 10
		}
		resultChan <- sum
	}

}
